﻿
using Autofac;
using Castle.DynamicProxy;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Redbus.Events;
using Redbus.Interfaces;
using SqlSugar;
using WCS.Entities;

namespace WCS.Services.CommandService
{

    /// <summary>
    /// 任务完成拦截器
    /// </summary>
    public class CommnadInterceptor : AsyncInterceptorBase
    {
        #region Fileds
        private readonly ILogger<CommnadInterceptor> logger;
        private readonly IOptionsMonitor<SystemParameter> options;
        private readonly IEventBus eventBus;
        private readonly MesWmsToolHelper mesWmsToolHelper;
        private readonly ILifetimeScope lifetimeScope;
        #endregion


        public CommnadInterceptor(
            ILogger<CommnadInterceptor> logger,
            IOptionsMonitor<SystemParameter> options,
            IEventBus eventBus,
            MesWmsToolHelper mesWmsToolHelper,
            ILifetimeScope lifetimeScope)
        {
            this.logger = logger;
            this.options = options;
            this.eventBus = eventBus;
            this.mesWmsToolHelper = mesWmsToolHelper;
            this.lifetimeScope = lifetimeScope;
        }

        /// <summary>
        /// 方法执行前
        /// </summary>
        /// <param name="invocation"></param>
        protected override void BeforeProceed(IInvocation invocation)
        {
            if (invocation.TargetType.Name.Contains("Storage"))
            {
                Procceed(invocation);
            }
            else
            {
                #region 方法执行前
                var isChecked = (typeof(CommandAttribute).GetType().
                    GetCustomAttributes(true).
                    FirstOrDefault(x => x is CommandAttribute) as CommandAttribute)?.
                    IsCheckedDistance ?? false;

                if (invocation.Arguments[1] != null && options.CurrentValue.IsPositionCheck && isChecked)
                {

                    var port = invocation.Arguments.FirstOrDefault(x => x.GetType() == typeof(TransferPort)) as TransferPort;
                    Procceed(invocation);
                    invocation.ReturnValue = Task.FromResult(false);
                }
                else
                {
                    Procceed(invocation);
                }


                #endregion
            }

        }

        /// <summary>
        /// 异步方法执行后
        /// </summary>
        /// <param name="invocation"></param>
        protected override Task AfterProceedAsync(IInvocation invocation, bool hasAsynResult)
        {
            try
            {
                using (var scope = lifetimeScope.BeginLifetimeScope())
                {
                    // var db = DbScoped.SugarScope.CopyNew();
                    var db = scope.Resolve<ISqlSugarClient>().CopyNew();
                    if (invocation.TargetType.Name.Contains("Storage"))
                    {
                        return Task.CompletedTask;
                    }
                    else
                    {
                        var finalResult = hasAsynResult ? (Task<bool>)invocation.ReturnValue : Task.FromResult((bool)invocation.ReturnValue);//最后运行结果
                        finalResult.ContinueWith(t =>
                        {
                            try
                            {
                                if (t.Result)
                                {
                                    //状态改变
                                    if (invocation.TargetType.Name.Contains("Finished"))
                                    {
                                        
                                    }

                                    if (invocation.TargetType.Name.Contains("Cancel"))
                                    {
                                       
                                    }
                                }
                                else
                                {
                                    TransferPort tranferPort = null;
                                    if (invocation.Arguments[1] != null)
                                        tranferPort = invocation.Arguments[1] as TransferPort; //料口
                                    //eventBus.PublishNotice(new WarningInfo
                                    //{
                                    //    Title = "对接警告",
                                    //    CreateTime = DateTime.Now,
                                    //    Message = $"failed!"

                                    //}, logger);
                                }
                                eventBus.Publish(new PayloadEvent<string>("ChangeStatus"));
                            }
                            catch (Exception ex)
                            {


                                logger.LogError("Excute the AfterProceedAsync  method in correct result,when the method ({0}),the error is:{1}", invocation.Method, ex.Message);
                            }



                        }
                        );
                        return Task.CompletedTask;
                    }
                }



            }
            catch (Exception ex)
            {

                logger.LogError("Excute the AfterProceedAsync method error,when the method ({0}),the error is:{1}", invocation.Method, ex.Message);
                return Task.CompletedTask;
            }


        }

    }
}
